#include <iostream>
using namespace std;


class A{
public:
    virtual void a(){ cout << "A::a()" << endl; } 
    virtual void b(){ cout << "A::b()" << endl; } 
    virtual void c(){ cout << "A::c()" << endl; } 
};

class B{
public:
    virtual void a(){ cout << "B::a()" << endl; } 
    virtual void b(){ cout << "B::b()" << endl; } 
    void c(){ cout << "B::c()" << endl; } 
    void d(){ cout << "B::d()" << endl; } 
};

class C
: public A
, public B
{
public:
    virtual void a(){ cout << "C::a()" << endl; } 
    void c(){ cout << "C::c()" << endl; } 
    void d(){ cout << "C::d()" << endl; } 
};


//先不看D类
class D
: public C
{
// public:
    void c(){ cout << "D::c()" << endl; }
};

void test01(){
    C c;
    c.a(); 
    // c.b(); 
    c.c(); 
    c.d(); 
    
    cout << endl;
    A* pa = &c;
    pa->a();  // 动态多态
    pa->b();  // 会通过虚函数表，但是没有覆盖
    pa->c();  // 动态多态
    // pa->d(); // A类中没有这个成员函数
    
    cout << endl;
    B* pb = &c;
    pb->a(); // 动态多态
    pb->b(); // 会通过虚函数表，但是没有覆盖
    pb->c(); // 普通函数，不通过虚函数表
    pb->d(); // 普通函数，不通过虚函数表


    cout << endl;
    C * pc = &c;
    pc->a();  // 用指针调用虚函数，就会通过虚函数表，但是不是动态多态
    // pc->b(); // 成员名访问冲突二义性
    pc->c(); // c函数对于C类而言，是虚函数，会通过虚函数表
    pc->d();  // 隐藏

    D d;
    pc = &d; // 通过C类指针指向d对象
    pc->c(); // 即使调用的函数在D类中是私有函数，也能调用到，因为C类中的c函数被D类的c函数覆盖掉了
}

int main(void){
    test01();

    return 0;
}